from typing import Dict, List, Optional
from datetime import datetime, timedelta
import pandas as pd
import logging
from .database import Database

logger = logging.getLogger(__name__)

class DataManager:
    """数据管理器"""
    
    def __init__(self, db_url: str = 'sqlite:///crypto_robot.db'):
        """
        初始化数据管理器
        
        Args:
            db_url: 数据库连接URL
        """
        self.db = Database(db_url)
        self.db.init_db()
        
    def store_market_data(self, exchange: str, symbol: str, data: pd.DataFrame):
        """
        存储市场数据
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            data: K线数据DataFrame
        """
        try:
            for _, row in data.iterrows():
                market_data = {
                    'exchange': exchange,
                    'symbol': symbol,
                    'timestamp': row.name if isinstance(row.name, datetime) else pd.to_datetime(row.name),
                    'open': float(row['open']),
                    'high': float(row['high']),
                    'low': float(row['low']),
                    'close': float(row['close']),
                    'volume': float(row['volume'])
                }
                self.db.save_market_data(market_data)
        except Exception as e:
            logger.error(f"Error storing market data: {str(e)}")
            raise
            
    def store_orderbook(self, exchange: str, symbol: str, orderbook: Dict):
        """
        存储订单簿数据
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            orderbook: 订单簿数据
        """
        try:
            timestamp = datetime.utcnow()
            
            # 存储买单
            for price, amount in orderbook['bids']:
                data = {
                    'exchange': exchange,
                    'symbol': symbol,
                    'timestamp': timestamp,
                    'side': 'bid',
                    'price': float(price),
                    'amount': float(amount)
                }
                self.db.save_orderbook(data)
                
            # 存储卖单
            for price, amount in orderbook['asks']:
                data = {
                    'exchange': exchange,
                    'symbol': symbol,
                    'timestamp': timestamp,
                    'side': 'ask',
                    'price': float(price),
                    'amount': float(amount)
                }
                self.db.save_orderbook(data)
        except Exception as e:
            logger.error(f"Error storing orderbook: {str(e)}")
            raise
            
    def store_trade(self, trade_data: Dict):
        """
        存储交易记录
        
        Args:
            trade_data: 交易数据
        """
        try:
            self.db.save_trade(trade_data)
        except Exception as e:
            logger.error(f"Error storing trade: {str(e)}")
            raise
            
    def store_position(self, position_data: Dict):
        """
        存储持仓记录
        
        Args:
            position_data: 持仓数据
        """
        try:
            self.db.save_position(position_data)
        except Exception as e:
            logger.error(f"Error storing position: {str(e)}")
            raise
            
    def store_trading_signal(self, signal_data: Dict):
        """
        存储交易信号
        
        Args:
            signal_data: 信号数据
        """
        try:
            self.db.save_trading_signal(signal_data)
        except Exception as e:
            logger.error(f"Error storing trading signal: {str(e)}")
            raise
            
    def get_historical_data(self, exchange: str, symbol: str,
                          start_time: datetime, end_time: datetime) -> pd.DataFrame:
        """
        获取历史市场数据
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            start_time: 开始时间
            end_time: 结束时间
            
        Returns:
            历史数据DataFrame
        """
        try:
            return self.db.get_market_data(exchange, symbol, start_time, end_time)
        except Exception as e:
            logger.error(f"Error getting historical data: {str(e)}")
            return pd.DataFrame()
            
    def get_recent_trades(self, exchange: str, symbol: str, limit: int = 100) -> List[Dict]:
        """
        获取最近的交易记录
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            limit: 返回记录数量
            
        Returns:
            交易记录列表
        """
        try:
            return self.db.get_latest_trades(exchange, symbol, limit)
        except Exception as e:
            logger.error(f"Error getting recent trades: {str(e)}")
            return []
            
    def get_active_positions(self, exchange: str = None) -> List[Dict]:
        """
        获取当前活跃持仓
        
        Args:
            exchange: 交易所名称（可选）
            
        Returns:
            持仓记录列表
        """
        try:
            return self.db.get_open_positions(exchange)
        except Exception as e:
            logger.error(f"Error getting active positions: {str(e)}")
            return []
            
    def get_active_signals(self, exchange: str = None) -> List[Dict]:
        """
        获取未执行的交易信号
        
        Args:
            exchange: 交易所名称（可选）
            
        Returns:
            未执行的交易信号列表
        """
        try:
            return self.db.get_pending_signals(exchange)
        except Exception as e:
            logger.error(f"Error getting active signals: {str(e)}")
            return []
            
    def update_signal_status(self, signal_id: int):
        """
        更新信号状态为已执行
        
        Args:
            signal_id: 信号ID
        """
        try:
            self.db.mark_signal_executed(signal_id)
        except Exception as e:
            logger.error(f"Error updating signal status: {str(e)}")
            
    def cleanup_database(self, days: int = 30):
        """
        清理旧数据
        
        Args:
            days: 保留最近多少天的数据
        """
        try:
            self.db.cleanup_old_data(days)
            logger.info(f"Successfully cleaned up data older than {days} days")
        except Exception as e:
            logger.error(f"Error cleaning up database: {str(e)}")
            
    def get_daily_summary(self, exchange: str, symbol: str, date: datetime) -> Dict:
        """
        获取每日交易汇总
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            date: 日期
            
        Returns:
            每日汇总数据
        """
        try:
            start_time = date.replace(hour=0, minute=0, second=0, microsecond=0)
            end_time = start_time + timedelta(days=1)
            
            # 获取当日K线数据
            df = self.get_historical_data(exchange, symbol, start_time, end_time)
            
            if df.empty:
                return {}
                
            # 获取当日交易记录
            trades = self.get_recent_trades(exchange, symbol)
            trades = [t for t in trades if start_time <= t['timestamp'] < end_time]
            
            # 计算交易统计
            total_volume = sum(t['amount'] for t in trades)
            total_value = sum(t['amount'] * t['price'] for t in trades)
            avg_price = total_value / total_volume if total_volume > 0 else 0
            
            return {
                'date': date.date(),
                'open': df.iloc[0]['open'],
                'high': df['high'].max(),
                'low': df['low'].min(),
                'close': df.iloc[-1]['close'],
                'volume': df['volume'].sum(),
                'trade_count': len(trades),
                'trade_volume': total_volume,
                'avg_trade_price': avg_price
            }
        except Exception as e:
            logger.error(f"Error getting daily summary: {str(e)}")
            return {}
